/*
 *  Matrix3.cpp
 *  RTDemo
 *
 *  Created by steveca  on 29/04/09.
 *  Copyright 2009 __MyCompanyName__. All rights reserved.
 *
 */

#include "Matrix3.h"

namespace RTRT
{
    const float Matrix3::EPSILON = 1e-06;
    const Matrix3 Matrix3::ZERO(0,0,0,0,0,0,0,0,0);
    const Matrix3 Matrix3::IDENTITY(1,0,0,0,1,0,0,0,1);
    
    
    Vector3 Matrix3 :: getColumn(size_t column) const
    {
        assert( 0 <= column && column < 3);
        return Vector3(m[0][column], m[1][column], m[2][column]);
    }
    
    void Matrix3 :: setColumn(size_t column, const Vector3& vec)
    {
        assert( 0 <= column && column < 3);
        m[0][column] = vec.x;
        m[1][column] = vec.y; 
        m[2][column] = vec.z;
    }
 
    bool Matrix3 :: operator == (const Matrix3& _matrix) const
    {
        for (size_t i = 0; i < 3; i ++)
        {
            for (size_t j = 0; j < 3; j ++)
            {
                if (m[i][j] != _matrix.m[i][j])
                    return false;
            }
        }
        return true;
    }
    
    Matrix3 Matrix3 :: operator + (const Matrix3& _matrix) const
    {
        Matrix3 sumMat;
        for (size_t i = 0; i < 3; i ++)
        {
            for (size_t j = 0; j < 3; j ++)
            {
                sumMat.m[i][j] = m[i][j] + _matrix.m[i][j];
            }
        }
        return sumMat;
    }
    
    Matrix3 Matrix3 :: operator - (const Matrix3& _matrix) const
    {
        Matrix3 diffMat;
        for (size_t i = 0; i < 3; i ++)
        {
            for (size_t j = 0; j < 3; j ++)
            {
                diffMat.m[i][j] = m[i][j] + _matrix.m[i][j];
            }
        }
        return diffMat;
    }
    
    Matrix3 Matrix3 :: operator * (const Matrix3& _matrix) const
    {
        Matrix3 prodMat;
        for (size_t i = 0; i < 3; i ++)
        {
            for (size_t j = 0; j < 3; j ++)
            {
                prodMat.m[i][j] = 
                    m[i][0] * _matrix.m[0][j] +
                    m[i][1] * _matrix.m[1][j] +
                    m[i][2] * _matrix.m[2][j];
            }
        }
        return prodMat;
    }
    
    Matrix3 Matrix3 :: operator - () const
    {
        Matrix3 mat;
        for (size_t i = 0; i < 3; i ++)
        {
            for (size_t j = 0; j < 3; j ++)
            {
                mat.m[i][j] = -m[i][j];
            }
        }
        
        return mat; 
    }
    
    Vector3 Matrix3 :: operator * (const Vector3& _vector) const
    {
        Vector3 vec;
        
        vec.x = m[0][0] * _vector.x + m[0][1] * _vector.y + m[0][2] * _vector.z;
        vec.y = m[1][0] * _vector.x + m[1][1] * _vector.y + m[1][2] * _vector.z;
        vec.z = m[2][0] * _vector.x + m[2][1] * _vector.y + m[2][2] * _vector.z;
        
        return vec;
    }
    
    Vector3 operator * (const Vector3& _vector, const Matrix3& _matrix)
    {
        Vector3 prodVec;
        for (size_t i = 0; i < 3; i ++)
        {
            prodVec[i] = _vector[0] * _matrix.m[0][i] + _vector[1] * _matrix.m[1][i] + _vector[2] * _matrix[2][i];
        }
        
        return prodVec;
    }
    
    Matrix3 Matrix3 :: operator * (const float scaler) const
    {
        Matrix3 prodMat;
        
        for (size_t i = 0; i < 3; i ++)
        {
            for (size_t j = 0; j < 3; j ++)
            {
                prodMat.m[i][j] = m[i][j] * scaler;
            }
        }
        
        return prodMat;
    }
    
    Matrix3 operator * (const float scaler, const Matrix3& _matrix) const
    {
        Matrix3 prodMat;
        
        for (size_t i = 0; i < 3; i ++)
        {
            for (size_t j = 0; j < 3; j ++)
            {
                prodMat.m[i][j] = _matrix.m[i][j] * scaler;
            }
        }
        
        return prodMat;
    }
    
    Matrix3 Matrix3 :: transpose() const
    {
        
    }
    
    bool Matrix3 :: inverse(Matrix3& _matrix, float tolerance) const
    {
        
    }
    
    Matrix3 Matrix3 :: inverse(float tolerance) const
    {
    }
    
    float determinant() const
    {
    }
    
    
    
}

